package com.app.oral.controller

import com.app.oral.config.ApiResponse
import com.app.oral.dto.TeacherClassStudentsResponse
import com.app.oral.dto.TeacherStudentDetailDto
import com.app.oral.dto.TeacherStudentDto
import com.app.oral.model.AccountStatus
import com.app.oral.model.UserType
import com.app.oral.service.ClassService
import com.app.oral.service.ExerciseRecordService
import com.app.oral.service.UserService
import com.app.oral.service.UserSessionService
import com.app.oral.util.TeacherPermissionHelper
import com.app.oral.util.UserResponseHelper
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.responses.ApiResponses
import io.swagger.v3.oas.annotations.security.SecurityRequirement
import io.swagger.v3.oas.annotations.tags.Tag
import jakarta.servlet.http.HttpServletRequest
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import io.swagger.v3.oas.annotations.responses.ApiResponse as SwaggerApiResponse

@RestController
@RequestMapping("/api/v1/users")
@Tag(name = "用户管理", description = "用户信息管理、审核、个人资料等功能")
class UsersController(
    private val userService: UserService,
    private val classService: ClassService,
    private val userSessionService: UserSessionService,
    private val exerciseRecordService: ExerciseRecordService,
    private val teacherPermissionHelper: TeacherPermissionHelper
) {

    @Operation(
        summary = "获取用户列表",
        description = "获取所有用户列表，支持按搜索关键词、状态、用户类型筛选（管理员功能）"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "获取成功")
    ])
    @SecurityRequirement(name = "SessionAuth")
    @GetMapping
    fun getAllUsers(
        @Parameter(description = "搜索关键词（姓名或昵称）") @RequestParam(required = false) search: String?,
        @Parameter(description = "账号状态筛选") @RequestParam(required = false) status: String?,
        @Parameter(description = "用户类型筛选") @RequestParam(required = false) userType: String?
    ): ApiResponse<List<Map<String, Any>>> {
        
        try {
            // 获取所有用户
            val users = userService.getAllUsers()
            
            // 过滤用户
            val filteredUsers = users.filter { user ->
                // 搜索过滤
                val searchMatch = search?.let { searchTerm ->
                    user.realName.contains(searchTerm, ignoreCase = true) || user.nickname.contains(searchTerm, ignoreCase = true)
                } ?: true
                
                // 状态过滤
                val statusMatch = status?.let { 
                    user.accountStatus.name == it
                } ?: true
                
                // 用户类型过滤
                val typeMatch = userType?.let { 
                    user.userType?.name == it 
                } ?: true
                
                searchMatch && statusMatch && typeMatch
            }
            
            // 转换为前端需要的格式
            val result = UserResponseHelper.buildUserResponseList(filteredUsers, classService)
            
            return ApiResponse.ok("获取用户列表成功", result)
            
        } catch (e: Exception) {
            return ApiResponse.error("获取用户列表失败: ${e.message}")
        }
    }

    @Operation(
        summary = "批准用户",
        description = "管理员批准待审核用户（管理员功能）"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "批准成功"),
        SwaggerApiResponse(responseCode = "400", description = "批准失败")
    ])
    @SecurityRequirement(name = "SessionAuth")
    @PostMapping("/approve")
    fun approveUser(
        @Parameter(description = "用户ID") @RequestParam userId: Long
    ): ApiResponse<String> {
        return try {
            val success = userService.approveUser(userId)
            if (success) {
                ApiResponse.ok("用户批准成功")
            } else {
                ApiResponse.error("用户批准失败，请检查用户ID")
            }
        } catch (e: Exception) {
            ApiResponse.error("用户批准失败: ${e.message}")
        }
    }

    @Operation(
        summary = "拒绝用户",
        description = "管理员拒绝待审核用户（管理员功能）"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "拒绝成功"),
        SwaggerApiResponse(responseCode = "400", description = "拒绝失败")
    ])
    @SecurityRequirement(name = "SessionAuth")
    @PostMapping("/reject")
    fun rejectUser(
        @Parameter(description = "用户ID") @RequestParam userId: Long
    ): ApiResponse<String> {
        return try {
            val success = userService.rejectUser(userId)
            if (success) {
                ApiResponse.ok("用户拒绝成功")
            } else {
                ApiResponse.error("用户拒绝失败，请检查用户ID")
            }
        } catch (e: Exception) {
            ApiResponse.error("用户拒绝失败: ${e.message}")
        }
    }

    @Operation(
        summary = "删除用户",
        description = "管理员删除用户及其所有相关数据（包括会话记录、练习记录等）"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "删除成功"),
        SwaggerApiResponse(responseCode = "400", description = "删除失败"),
        SwaggerApiResponse(responseCode = "404", description = "用户不存在")
    ])
    @SecurityRequirement(name = "SessionAuth")
    @DeleteMapping("/{userId}")
    fun deleteUser(
        @Parameter(description = "用户ID") @PathVariable userId: Long
    ): ApiResponse<String> {
        return try {
            val success = userService.deleteUser(userId)
            if (success) {
                ApiResponse.ok("用户删除成功")
            } else {
                ApiResponse.error("用户删除失败，用户不存在")
            }
        } catch (e: Exception) {
            ApiResponse.error("用户删除失败: ${e.message}")
        }
    }

    @Operation(
        summary = "获取用户统计信息",
        description = "获取各状态用户数量统计（管理员功能）"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "统计信息获取成功")
    ])
    @SecurityRequirement(name = "SessionAuth")
    @GetMapping("/statistics")
    fun getUserStatistics(): ApiResponse<Map<String, Int>> {
        return try {
            val users = userService.getAllUsers()
            val statistics = mapOf(
                "total" to users.size,
                "pending" to users.count { it.accountStatus == AccountStatus.PENDING },
                "approved" to users.count { it.accountStatus == AccountStatus.APPROVED },
                "rejected" to users.count { it.accountStatus == AccountStatus.REJECTED },
                "incomplete" to users.count { it.accountStatus == AccountStatus.INCOMPLETE }
            )
            
            ApiResponse.ok("获取统计信息成功", statistics)
        } catch (e: Exception) {
            ApiResponse.error("获取统计信息失败: ${e.message}")
        }
    }

    @Operation(
        summary = "完善用户资料",
        description = "用户完善个人资料信息，提交后等待管理员审核（小程序用户功能）"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "信息完善成功"),
        SwaggerApiResponse(responseCode = "400", description = "参数错误或信息完善失败"),
        SwaggerApiResponse(responseCode = "401", description = "会话无效")
    ])
    @SecurityRequirement(name = "BearerAuth")
    @PostMapping("/complete-profile")
    fun completeProfile(
        @Parameter(description = "用户资料信息") @RequestBody profileData: Map<String, Any>,
        @Parameter(hidden = true) request: HttpServletRequest
    ): ApiResponse<String> {
        val sessionKey = request.getHeader("Authorization")?.removePrefix("Bearer ")
            ?: return ApiResponse.error("缺少会话令牌")

        // 验证会话
        val session = userSessionService.validateSession(sessionKey)
            ?: return ApiResponse.error("会话无效或已过期，请重新登录")

        // 更新会话访问时间
        userSessionService.updateSessionAccess(sessionKey)

        val user = userService.getOrCreateUser(session.openid)
        if (user.id == null) {
            return ApiResponse.error("用户不存在")
        }

        val realName = profileData["realName"] as? String ?: ""
        val gender = profileData["gender"] as? String ?: "MALE"
        val userType = profileData["userType"] as? String ?: "STUDENT"
        val classId = when (val classIdValue = profileData["classId"]) {
            is Number -> classIdValue.toLong()
            is String -> classIdValue.toLongOrNull()
            else -> null
        }

        if (realName.isEmpty()) {
            return ApiResponse.error("请填写真实姓名")
        }

        val success = userService.completeProfile(user.id, realName, gender, userType, classId)
        return if (success) {
            ApiResponse.ok("信息完善成功，请等待审核")
        } else {
            ApiResponse.error("信息完善失败")
        }
    }

    @Operation(
        summary = "获取个人资料",
        description = "获取当前登录用户的个人资料信息（小程序用户功能）"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "获取成功"),
        SwaggerApiResponse(responseCode = "401", description = "会话无效")
    ])
    @SecurityRequirement(name = "BearerAuth")
    @GetMapping("/profile")
    fun getUserProfile(
        @Parameter(hidden = true) request: HttpServletRequest
    ): ApiResponse<Map<String, Any>> {
        val sessionKey = request.getHeader("Authorization")?.removePrefix("Bearer ")
            ?: return ApiResponse.error("缺少会话令牌")

        // 验证会话
        val session = userSessionService.validateSession(sessionKey)
            ?: return ApiResponse.error("会话无效或已过期，请重新登录")

        // 更新会话访问时间
        userSessionService.updateSessionAccess(sessionKey)

        // 获取用户信息
        val user = userService.getOrCreateUser(session.openid)
        
        val userWithClassName = UserResponseHelper.buildUserResponseList(listOf(user), classService).first()

        val response = mutableMapOf(
            "user" to userWithClassName,
            "needCompleteProfile" to (user.accountStatus == AccountStatus.INCOMPLETE),
            "isPending" to (user.accountStatus == AccountStatus.PENDING),
            "isApproved" to (user.accountStatus == AccountStatus.APPROVED),
            "isRejected" to (user.accountStatus == AccountStatus.REJECTED)
        )

        return ApiResponse.ok("获取用户资料成功", response)
    }

    @Operation(
        summary = "根据用户类型查询用户列表",
        description = "根据用户类型（STUDENT/TEACHER）查询用户列表，返回用户基本信息和激活状态"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "查询成功"),
        SwaggerApiResponse(responseCode = "400", description = "参数错误")
    ])
    @GetMapping("/by-type/{userType}")
    fun getUsersByType(
        @Parameter(description = "用户类型：STUDENT/TEACHER") @PathVariable userType: String
    ): ApiResponse<List<Map<String, Any>>> {
        
        return try {
            // 验证用户类型参数
            val validUserType = when (userType.uppercase()) {
                "STUDENT", "TEACHER" -> userType.uppercase()
                "学生" -> "STUDENT"
                "教师" -> "TEACHER"
                else -> return ApiResponse.error("无效的用户类型，请使用：STUDENT、TEACHER、学生、教师")
            }
            
            // 查询指定类型的用户
            val users = userService.getUsersByType(validUserType)
            
            // 转换为前端需要的格式
            val result = UserResponseHelper.buildUserResponseList(users, classService)
            
            ApiResponse.ok("查询${if (validUserType == "STUDENT") "学生" else "教师"}用户列表成功", result)
            
        } catch (e: Exception) {
            ApiResponse.error("查询用户列表失败: ${e.message}")
        }
    }

    /**
     * 教师专用 - 获取班级学生列表
     */
    @Operation(
        summary = "获取班级学生列表",
        description = "教师查看指定班级的学生信息和练习统计"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "获取成功"),
        SwaggerApiResponse(responseCode = "403", description = "权限不足"),
        SwaggerApiResponse(responseCode = "404", description = "班级不存在")
    ])
    @SecurityRequirement(name = "BearerAuth")
    @GetMapping("/teacher/class/{classId}/students")
    fun getTeacherClassStudents(
        @Parameter(description = "班级ID") @PathVariable classId: Long,
        request: HttpServletRequest
    ): ResponseEntity<ApiResponse<TeacherClassStudentsResponse>> {
        // 验证教师身份
        val teacher = teacherPermissionHelper.validateTeacher(request)
            ?: return ResponseEntity.status(403).body(
                ApiResponse.error("权限不足，只有教师可以访问")
            )

        // 验证教师是否可以访问该班级
        if (!teacherPermissionHelper.canAccessClass(teacher, classId)) {
            return ResponseEntity.status(403).body(
                ApiResponse.error("权限不足，无法访问该班级")
            )
        }

        return try {
            // 获取班级信息
            val classInfo = classService.getClassById(classId)
                ?: return ResponseEntity.status(404).body(
                    ApiResponse.error("班级不存在")
                )

            // 获取班级内的学生
            val students = userService.getUsersByClassId(classId)
                .filter { it.userType == UserType.STUDENT }

            val studentDtos = students.map { student ->
                val statistics = exerciseRecordService.getUserStatistics(student.id!!)
                
                TeacherStudentDto(
                    userId = student.id,
                    realName = student.realName,
                    classId = classId,
                    className = classInfo.className,
                    totalRecords = statistics.totalRecords,
                    completedRecords = statistics.completedRecords,
                    averageScore = statistics.averageScore
                )
            }

            val response = TeacherClassStudentsResponse(
                classId = classId,
                className = classInfo.className,
                students = studentDtos
            )

            ResponseEntity.ok(ApiResponse.ok("获取班级学生列表成功", response))
        } catch (e: Exception) {
            ResponseEntity.internalServerError().body(
                ApiResponse.error("获取班级学生列表失败")
            )
        }
    }

    /**
     * 教师专用 - 获取学生详细信息
     */
    @Operation(
        summary = "获取学生详情",
        description = "教师查看指定学生的详细信息和练习统计"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "获取成功"),
        SwaggerApiResponse(responseCode = "403", description = "权限不足"),
        SwaggerApiResponse(responseCode = "404", description = "学生不存在")
    ])
    @SecurityRequirement(name = "BearerAuth")
    @GetMapping("/teacher/student/{studentId}")
    fun getTeacherStudentDetail(
        @Parameter(description = "学生用户ID") @PathVariable studentId: Long,
        request: HttpServletRequest
    ): ResponseEntity<ApiResponse<TeacherStudentDetailDto>> {
        // 验证教师身份
        val teacher = teacherPermissionHelper.validateTeacher(request)
            ?: return ResponseEntity.status(403).body(
                ApiResponse.error("权限不足，只有教师可以访问")
            )

        // 验证教师是否可以访问该学生
        if (!teacherPermissionHelper.canAccessStudent(teacher, studentId)) {
            return ResponseEntity.status(403).body(
                ApiResponse.error("权限不足，无法访问该学生信息")
            )
        }

        return try {
            // 获取学生信息
            val student = userService.getUserById(studentId)
                ?: return ResponseEntity.status(404).body(
                    ApiResponse.error("学生不存在")
                )

            // 获取学生的班级信息
            val studentClassIds = student.getClassIdList()
            val className = studentClassIds.firstOrNull()?.let { classId ->
                classService.getClassById(classId)?.className
            }

            // 获取练习统计
            val statistics = exerciseRecordService.getUserStatistics(studentId)

            val studentDetail = TeacherStudentDetailDto(
                userId = student.id!!,
                realName = student.realName,
                gender = student.gender.toString(),
                classId = studentClassIds.firstOrNull() ?: 0L,
                className = className,
                accountStatus = student.accountStatus.name,
                totalRecords = statistics.totalRecords,
                practiceRecords = statistics.practiceRecords,
                testRecords = statistics.testRecords,
                completedRecords = statistics.completedRecords,
                averageScore = statistics.averageScore
            )

            ResponseEntity.ok(ApiResponse.ok("获取学生详情成功", studentDetail))
        } catch (e: Exception) {
            ResponseEntity.internalServerError().body(
                ApiResponse.error("获取学生详情失败")
            )
        }
    }
}